package main

import "fmt"

func main() {
	s := someStruct{name: "example"}
	foo(s)
	gkd(1)
	ggg(3)
}

type someInterFaceA interface {
	doSomethingA()
}
type someInterFaceB interface {
	doSomethingB()
}

type someStruct struct {
	name string
}

func (s someStruct) doSomethingA() {
	println("A: Doing something with", s.name)
}
func (s someStruct) doSomethingB() {
	println("B: Doing something with", s.name)
}

// 泛型 与
func foo[T interface {
	someInterFaceA
	someInterFaceB
}](p T) {
	p.doSomethingA()
	p.doSomethingB()
}

// 泛型或
// T 只能是列出的具体类型（不能带方法！）
func gkd[T interface{ int | string }](p T) {
	// func gkd[T int | string](p T) {
	fmt.Println(p)
}

// 对于复杂类型需要先退化到any再使用断言
// func ggg[T any](p T) {
// 	if v, ok := p.(someInterFaceA); ok {
// 		v.doSomethingA()
// 	}
// 	fmt.Println(p)
// }
func ggg(p any) {
	if v, ok := p.(someInterFaceA); ok {
		v.doSomethingA()
	}
	fmt.Println(p)
}
